package com.techsoul.module.baoli.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.BusinessException;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.core.util.lang.DateUtils;
import com.techsoul.common.core.util.lang.StringUtils;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.baoli.enmus.FinCreditBillStatusEnum;
import com.techsoul.module.baoli.enmus.FinFinanceApplyEnum;
import com.techsoul.module.baoli.mapper.FinCreditBillMapper;
import com.techsoul.module.baoli.mapper.FinFinanceApplyMapper;
import com.techsoul.module.baoli.pojo.entity.FinCreditBill;
import com.techsoul.module.baoli.pojo.entity.FinFinanceApply;
import com.techsoul.module.baoli.pojo.param.FinCreditBillSaveParam;
import com.techsoul.module.baoli.pojo.param.FinCreditBillSearchParam;
import com.techsoul.module.baoli.pojo.vo.FinCreditBillVo;
import com.techsoul.module.baoli.service.IFinCreditBillService;
import com.techsoul.module.basic.mapper.BaoliCompanyMapper;
import com.techsoul.module.basic.mapper.CustomerMapper;
import com.techsoul.module.basic.mapper.StoreMapper;
import com.techsoul.module.basic.mapper.SupplierMapper;
import com.techsoul.module.basic.pojo.vo.BaoliCompanyVo;
import com.techsoul.module.basic.pojo.vo.CustomerVo;
import com.techsoul.module.basic.pojo.vo.StoreVo;
import com.techsoul.module.basic.pojo.vo.SupplierVo;
import com.techsoul.module.system.service.IGeneralSeqService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.function.Supplier;

/**
 * 企业白条主 Service实现
 *
 * @author liuen
 * @date 2022-03-28
 */
@Service
@Transactional(readOnly = true)
public class FinCreditBillServiceImpl implements IFinCreditBillService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private FinCreditBillMapper mapper;
    @Autowired
    private SupplierMapper supplierMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private BaoliCompanyMapper baoliCompanyMapper;
    @Autowired
    private FinFinanceApplyMapper finFinanceApplyMapper;
    @Autowired
    private TokenService tokenService;

    @Autowired
    private IGeneralSeqService generalSeqService;
    /**
     /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String insert(FinCreditBillSaveParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        FinCreditBill entity = new FinCreditBill();
        if(params.getCreditBillNo()==null||params.getCreditBillNo()==""){
            String billNo = this.generalSeqService.generateSeq("credit_bill_no");
            entity.setCreditBillNo(billNo);
        }

        if(params.getQty()==null){
            params.setQty(0.0);
        }
        BeanUtils.copyProperties(params, entity);


        SupplierVo supplier = this.supplierMapper.findById(params.getSalerNo());
        if(supplier!=null){
            entity.setSalerName(supplier.getSupplierName());
            entity.setReceiverName(supplier.getSupplierName());
            entity.setReceiverSite(supplier.getId());
            if(user.getCustomerId()!=null&&user.getCustomerId()!=""){
                CustomerVo customer = this.customerMapper.findById(user.getCustomerId());
                entity.setBuyerName(customer.getCustomerName());
                entity.setBuyerNo(customer.getId());
                if(customer.getBaoliCompanyNo()==null||customer.getBaoliCompanyNo()==""){
                    throw new BusinessException("保理公司未授信");
                }else{
                    entity.setBaoliReceiverSite(customer.getBaoliCompanyNo());
                    entity.setBaoliReceiverName(customer.getBaoliCompanyName());
                }
            }else if(user.getStoreId()!=null&&user.getStoreId()!=""){
                StoreVo storeVo = this.storeMapper.findById(user.getStoreId());
                entity.setBuyerName(storeVo.getStoreName());
                entity.setBuyerNo(storeVo.getId());
                if(storeVo.getBaoliCompanyNo()==null||storeVo.getBaoliCompanyNo()==""){
                    return "保理公司未授信";
                }else{
                    entity.setBaoliReceiverSite(storeVo.getBaoliCompanyNo());
                    entity.setBaoliReceiverName(storeVo.getBaoliCompanyName());
                }
            }
        }else{
            CustomerVo customer = this.customerMapper.findById(params.getSalerNo());
            entity.setSalerName(customer.getCustomerName());
            entity.setReceiverName(customer.getCustomerName());
            entity.setReceiverSite(customer.getId());
            if(user.getCustomerId()!=null&&user.getCustomerId()!=""){
                CustomerVo bcustomer = this.customerMapper.findById(user.getCustomerId());
                entity.setBuyerName(bcustomer.getCustomerName());
                entity.setBuyerNo(bcustomer.getId());
                if(bcustomer.getBaoliCompanyNo()==null||bcustomer.getBaoliCompanyNo()==""){
                    return "保理公司未授信";
                }else{
                    entity.setBaoliReceiverSite(bcustomer.getBaoliCompanyNo());
                    entity.setBaoliReceiverName(bcustomer.getBaoliCompanyName());
                }
            }else if(user.getStoreId()!=null&&user.getStoreId()!="") {
                StoreVo storeVo = this.storeMapper.findById(user.getStoreId());
                entity.setBuyerName(storeVo.getStoreName());
                entity.setBuyerNo(storeVo.getId());
                if (storeVo.getBaoliCompanyNo() == null || storeVo.getBaoliCompanyNo() == "") {
                    return "保理公司未授信";
                } else {
                    entity.setBaoliReceiverSite(storeVo.getBaoliCompanyNo());
                    entity.setBaoliReceiverName(storeVo.getBaoliCompanyName());
                }
            }
        }// end supplier null

        entity.setReceiverNo(params.getSalerNo());
       /* if(!params.getReceiverNo().equals(params.getSalerNo())){
            supplier = this.supplierMapper.findById(params.getReceiverNo());
            entity.setReceiverName(supplier.getSupplierName());
        }else{
            entity.setReceiverName(supplier.getSupplierName());
        }*/
        Double length = DateUtils.getDistanceOfTwoDate(entity.getOpenDate(),entity.getValidatedTo());
        entity.setValidateLength(length.intValue());

        entity.setSite(user.getSite());
        entity.setStatus(FinCreditBillStatusEnum.CREATED.getValue());

        entity.setId(idWorker.nextId() + "").preInsert(user.getId());
        this.mapper.insert(entity);
        return entity.getId();
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }

    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 签收
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String receive(FinCreditBillSaveParam params) {
        List<String> ids = params.getIds();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        if(ids==null){
            String id = params.getId();
            FinCreditBill finCreditBill
                    =this.mapper.selectById(id);
            if(params.getStatus().equals("RECPT")){
                finCreditBill.setStatus(FinCreditBillStatusEnum.RECPT.getValue());
            }else{
                finCreditBill.setStatus(FinCreditBillStatusEnum.REFUSE.getValue());
            }
            if(params.getRemark()!=null&&params.getRemark()!="") {
                String proveRemark = " 签收人:".concat(sysUser.getUserName()).concat(" 签收意见:").concat(params.getRemark());
                if (!StringUtils.isNull(finCreditBill.getRemark())) {

                    proveRemark = finCreditBill.getRemark().concat(proveRemark);
                }
                finCreditBill.setRemark(proveRemark);

            }
            finCreditBill.preUpdate(sysUser.getId());
            this.mapper.updateById(finCreditBill);
        }else{
            for(int i=0; i<ids.size(); i++){
                String id= ids.get(i);
                FinCreditBill finCreditBill
                        =this.mapper.selectById(id);
                if(params.getStatus().equals("RECPT")){
                    finCreditBill.setStatus(FinCreditBillStatusEnum.RECPT.getValue());
                }else{
                    finCreditBill.setStatus(FinCreditBillStatusEnum.REFUSE.getValue());
                }
                if(params.getRemark()!=null&&params.getRemark()!="") {
                    String proveRemark = " 签收人:".concat(sysUser.getUserName()).concat(" 签收意见:").concat(params.getRemark());
                    if (!StringUtils.isNull(finCreditBill.getRemark())) {

                        proveRemark = finCreditBill.getRemark().concat(proveRemark);
                    }
                    finCreditBill.setRemark(proveRemark);

                }
                finCreditBill.preUpdate(sysUser.getId());
                this.mapper.updateById(finCreditBill);
            }
        }

        return "success";
    }
    /**
     * 付款确认
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String paymentConfirm(FinCreditBillSaveParam params) {
        String id = params.getId();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        // for(int i=0; i<ids.size(); i++){
        //  String id= ids.get(i);
        FinCreditBill finCreditBill
                =this.mapper.selectById(id);

        if(params.getRemark()!=null&&params.getRemark()!="") {
            String proveRemark = " 付款人:".concat(sysUser.getUserName()).concat(" 确认意见:").concat(params.getRemark());
            if (!StringUtils.isNull(finCreditBill.getRemark())) {

                proveRemark = finCreditBill.getRemark().concat(proveRemark);
            }
            finCreditBill.setRemark(proveRemark);

        }
        if(params.getStatus().equals("prove")){
            finCreditBill.setStatus(FinCreditBillStatusEnum.PAYMENTWAIT.getValue());
        }else{
            finCreditBill.setStatus(FinCreditBillStatusEnum.REJECTPAY.getValue());
            return "success";
        }
        finCreditBill.preUpdate(sysUser.getId());
        this.mapper.updateById(finCreditBill);
        FinFinanceApply existfinFinanceApply =this.finFinanceApplyMapper.findByCreditBillNo(finCreditBill.getCreditBillNo());
        if(existfinFinanceApply!=null){
            this.finFinanceApplyMapper.deleteById(existfinFinanceApply.getId());
        }
        FinFinanceApply finFinanceApply = new FinFinanceApply();
        finFinanceApply.setBaoliSite(finCreditBill.getBaoliPayableSite());
        finFinanceApply.setBasicNo(finCreditBill.getBasicNo());
        finFinanceApply.setContractNo(finCreditBill.getContractNo());
        finFinanceApply.setInvoiceNo(finCreditBill.getInvoiceNo());
        finFinanceApply.setSite(finCreditBill.getReceiverSite());
        finFinanceApply.setCreditBillNo(finCreditBill.getCreditBillNo());
        finFinanceApply.setFinanceAmt(finCreditBill.getAmount());
        finFinanceApply.setProductName(finCreditBill.getProductName());
        finFinanceApply.setProductNo(finCreditBill.getProductNo());
        finFinanceApply.setFinanceIssueCompanyName(finCreditBill.getBuyerName());
        finFinanceApply.setFinanceIssueCompanyNo(finCreditBill.getBuyerNo());
        finFinanceApply.setFinanceApplyCompany(finCreditBill.getReceiverName());
        finFinanceApply.setFinanceApplyCompanyNo(finCreditBill.getReceiverNo());
        finFinanceApply.setStatus(FinFinanceApplyEnum.applied.getValue());
        BaoliCompanyVo baolicompanyVo = this.baoliCompanyMapper.findById(finCreditBill.getBaoliPayableSite());
        String billNo = this.generalSeqService.generateSeq("finance_bill_no");
        finFinanceApply.setFinanceOrderNo(billNo);
        //   Double days = DateUtils.getDistanceOfTwoDate(finCreditBill.getValidatedTo(),finCreditBill.getOpenDate());
        finFinanceApply.setFinanceDays(Long.valueOf(finCreditBill.getUseageDays()));
        finFinanceApply.setIsValid("1");
        finFinanceApply.setInterestAmt(String.valueOf(finCreditBill.getInterestAmt()));
        finFinanceApply.setInterestRate(String.valueOf(finCreditBill.getInterestRate()));
        finFinanceApply.setFinaceDate(finCreditBill.getFinaceDate());
        finFinanceApply.setFinanceProvideCompanyName(baolicompanyVo.getCompanyName());
        finFinanceApply.setFinanceProvideCompanyNo(finCreditBill.getBaoliPayableSite());
        finFinanceApply.setId(idWorker.nextId() + "").preInsert(sysUser.getId());
        this.finFinanceApplyMapper.insert(finFinanceApply);


        // }
        return "success";
    }

    /**
     * 贴现
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String cashOut(FinCreditBillSaveParam params) {
        String id = params.getId();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        // for(int i=0; i<ids.size(); i++){
        // String id= ids.get(i);
        FinCreditBill finCreditBill
                =this.mapper.selectById(id);

        if(params.getRemark()!=null&&params.getRemark()!="") {
            String proveRemark = " 申请融资人:".concat(sysUser.getUserName()).concat(" 申请意见:").concat(params.getRemark());
            if (!StringUtils.isNull(finCreditBill.getRemark())) {

                proveRemark = finCreditBill.getRemark().concat(proveRemark);
            }
            finCreditBill.setRemark(proveRemark);

        }
        finCreditBill.setInterestRate(params.getInterestRate());
        finCreditBill.setUseageDays(params.getUseageDays());
        finCreditBill.setInterestAmt(params.getInterestAmt());
        finCreditBill.setStatus(FinCreditBillStatusEnum.APPLYPAYMENT.getValue());
        finCreditBill.setBaoliPayableSite(params.getBaoliPayableSite());
        finCreditBill.setFinaceDate(params.getFinaceDate());
        finCreditBill.setApprovedBy(sysUser.getUserName());
        finCreditBill.setApprovedTime(new Date());
        finCreditBill.preUpdate(sysUser.getId());
        this.mapper.updateById(finCreditBill);
        FinFinanceApply finFinanceApply = this.finFinanceApplyMapper.findByCreditBillNo(finCreditBill.getCreditBillNo());
        if(finFinanceApply!=null){
            finFinanceApply.setStatus(FinFinanceApplyEnum.proved.getValue());
            finFinanceApply.preUpdate(sysUser.getId());
            this.finFinanceApplyMapper.updateById(finFinanceApply);
        }
        return "success";
    }

    @Transactional(readOnly = false)
    @Override
    public String cashOutProve(FinCreditBillSaveParam params) {
        List<String> ids = params.getIds();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        for(int i=0; i<ids.size(); i++){
            String id= ids.get(i);
            FinCreditBill finCreditBill
                    =this.mapper.selectById(id);
            if(params.getStatus().equals("prove")){
                finCreditBill.setStatus(FinCreditBillStatusEnum.CONFIRMPAY.getValue());
            }else{
                finCreditBill.setStatus(FinCreditBillStatusEnum.REJECTPAY.getValue());
            }
            if(params.getRemark()!=null&&params.getRemark()!="") {
                String proveRemark = " 平台复核人:".concat(sysUser.getUserName()).concat(" 复核意见:").concat(params.getRemark());
                if (!StringUtils.isNull(finCreditBill.getRemark())) {

                    proveRemark = finCreditBill.getRemark().concat(proveRemark);
                }
                finCreditBill.setRemark(proveRemark);

            }
            finCreditBill.setApprovedBy(sysUser.getUserName());
            finCreditBill.setApprovedTime(new Date());
            finCreditBill.preUpdate(sysUser.getId());
            this.mapper.updateById(finCreditBill);
        }
        return "success";
    }
    /**
     * 平台审核
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String platFormprove(FinCreditBillSaveParam params) {
        List<String> ids = params.getIds();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();

        for(int i=0; i<ids.size(); i++){
            String id= ids.get(i);
            FinCreditBill finCreditBill
                    =this.mapper.selectById(id);
            if(params.getStatus().equals("prove")){
                finCreditBill.setStatus(FinCreditBillStatusEnum.SENT.getValue());
            }else{
                finCreditBill.setStatus(FinCreditBillStatusEnum.DENY.getValue());
            }
            if(params.getRemark()!=null&&params.getRemark()!="") {
                String proveRemark = " 平台复核人:".concat(sysUser.getUserName()).concat(" 复核意见:").concat(params.getRemark());
                if (!StringUtils.isNull(finCreditBill.getRemark())) {

                    proveRemark = finCreditBill.getRemark().concat(proveRemark);
                }
                finCreditBill.setRemark(proveRemark);

            }
            finCreditBill.setApprovedBy(sysUser.getUserName());
            finCreditBill.setApprovedTime(new Date());
            finCreditBill.preUpdate(sysUser.getId());
            this.mapper.updateById(finCreditBill);
        }
        return "success";
    }
    /**
     * 申请处理批准
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String prove(FinCreditBillSaveParam params) {
        List<String> ids = params.getIds();
        UserVo sysUser = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        if(ids==null){
            String id = params.getId();
            FinCreditBill finCreditBill
                    = this.mapper.selectById(id);
            if (params.getStatus().equals("prove")) {
                finCreditBill.setStatus(FinCreditBillStatusEnum.CHECKED.getValue());
            } else {
                finCreditBill.setStatus(FinCreditBillStatusEnum.REJECT.getValue());
            }
            if (params.getRemark() != null && params.getRemark() != "") {
                String proveRemark = " 复核人:".concat(sysUser.getUserName()).concat(" 复核意见:").concat(params.getRemark());
                if (!StringUtils.isNull(finCreditBill.getRemark())) {

                    proveRemark = finCreditBill.getRemark().concat(proveRemark);
                }
                finCreditBill.setRemark(proveRemark);
            }


            finCreditBill.setApprovedBy(sysUser.getUserName());
            finCreditBill.setApprovedTime(new Date());
            finCreditBill.preUpdate(sysUser.getId());
            this.mapper.updateById(finCreditBill);
        }else {
            for (int i = 0; i < ids.size(); i++) {
                String id = ids.get(i);
                FinCreditBill finCreditBill
                        = this.mapper.selectById(id);
                if (params.getStatus().equals("prove")) {
                    finCreditBill.setStatus(FinCreditBillStatusEnum.CHECKED.getValue());
                } else {
                    finCreditBill.setStatus(FinCreditBillStatusEnum.REJECT.getValue());
                }
                if (params.getRemark() != null && params.getRemark() != "") {
                    String proveRemark = " 复核人:".concat(sysUser.getUserName()).concat(" 复核意见:").concat(params.getRemark());
                    if (!StringUtils.isNull(finCreditBill.getRemark())) {

                        proveRemark = finCreditBill.getRemark().concat(proveRemark);
                    }
                    finCreditBill.setRemark(proveRemark);
                }


                finCreditBill.setApprovedBy(sysUser.getUserName());
                finCreditBill.setApprovedTime(new Date());
                finCreditBill.preUpdate(sysUser.getId());
                this.mapper.updateById(finCreditBill);
            }
        }
        return "success";
    }
    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(FinCreditBillSaveParam params) {
        FinCreditBill entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(user.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public FinCreditBillVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<FinCreditBillVo> findAll(FinCreditBillSearchParam params) {
        return this.mapper.findAll(params);
    }

    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<FinCreditBillVo> findAll(FinCreditBillSearchParam params, Integer current, Integer pageSize) {
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }

    /**
     * 审核不通过惠单总数
     *
     * @return
     */
    @Override
    public Integer findTotalMyRejectBill(UserVo sysuser) {
        if(sysuser.getUserType()!=null&&sysuser.getUserType()!=""){
            if(sysuser.getUserType().equals("供应商")){
                return this.mapper.findTotalMyReceBill(sysuser.getSite(),FinCreditBillStatusEnum.DENY.getValue());
            }else if(sysuser.getUserType().equals("买家客户")){
                Integer rst =  this.mapper.findTotalMyIssuedBill(sysuser.getSite(),FinCreditBillStatusEnum.REFUSE.getValue());
                Integer rst2 = this.mapper.findTotalMyIssuedBill(sysuser.getSite(),FinCreditBillStatusEnum.DENY.getValue());
                rst = rst+rst2;
                return rst ;
            }else if(sysuser.getUserType().equals("贸易商")){
                Integer rst =  this.mapper.findTotalMyReceBill(sysuser.getSite(),FinCreditBillStatusEnum.DENY.getValue());
                Integer rst3 =  this.mapper.findTotalMyIssuedBill(sysuser.getSite(),FinCreditBillStatusEnum.REFUSE.getValue());
                Integer rst2 = this.mapper.findTotalMyIssuedBill(sysuser.getSite(),FinCreditBillStatusEnum.DENY.getValue());
                rst = rst+rst2+rst3;
                return rst ;
            }else{
                return 0;
            }
        }

        return 0;

    }
    /**
     * 待处理惠单总数
     *
     * @return
     */
    @Override
    public Integer findTotalMyBill(UserVo sysuser) {
        if(sysuser.getUserType()!=null&&sysuser.getUserType()!=""){
            if(sysuser.getUserType().equals("供应商")){
                return this.mapper.findTotalMyReceBill(sysuser.getSite(),FinCreditBillStatusEnum.CHECKED.getValue());
            }else if(sysuser.getUserType().equals("买家客户")){
                return this.mapper.findTotalMyIssuedBill(sysuser.getSite(),FinCreditBillStatusEnum.CREATED.getValue());
            }else if(sysuser.getUserType().equals("贸易商")){
                Integer rst =  this.mapper.findTotalMyReceBill(sysuser.getSite(),FinCreditBillStatusEnum.CHECKED.getValue());
                Integer rst2 = this.mapper.findTotalMyIssuedBill(sysuser.getSite(),FinCreditBillStatusEnum.CREATED.getValue());
                rst = rst+rst2;
                return rst ;
            }else{
                return this.mapper.findTotalMyProcessBill(sysuser.getSite());
            }
        }

        return 0;

    }

}
